/* 
 * File:   Fracciones.h
 * Author: bastian
 *
 * Created on 7 de mayo de 2011, 15:09
 */


#ifndef STDIO_H
#include <stdio.h>
#define STDIO_H
#endif

#ifndef STDLIB_H
#include <stdlib.h>
#define STDLIB_H
#endif

#ifndef MATH_H
#include <math.h>
#define MATH_H
#endif

typedef struct {
    long numerador;
    long denominador;
}Fraccion;


// Inicializa la variable Fraccion
Fraccion *Fraccion_new(){
    
    Fraccion *fra=NULL;
    fra = malloc(sizeof(Fraccion));
    fra->numerador=0;
    fra->denominador=1;
    return fra;
}

//Muestra la fraccion
void Fraccion_Mostrar(Fraccion *fra){

    if(fra->denominador==0)
        printf("\nCantidad Indeterminada");
    
    else if(fra->numerador==0)
        printf("0");
    
    else if(fra->denominador==1)
        printf("%i",fra->numerador);
    
    else
        printf("%i/%i",fra->numerador,fra->denominador);

}

//Asigna un valor a la fraccion
int Fraccion_setValue(Fraccion *fra,long numerador, long denominador){
    
    if(denominador == 0)
        return 1;
    else{
        fra->numerador=numerador;
        fra->denominador=denominador;
        return 0;
    }
    
}

//------------------------------------------------------------------------------
//Operaciones con fracciones

int MaximoComunDivisor(long a, long b){
    
    a=(long)fabs(a);
    b=(long)fabs(b);
    if(b == 0)
        return a;
    else
        return MaximoComunDivisor(b, a%b);
    
}

void Fraccion_Simplificar(Fraccion *fra){
    
    int MCD = MaximoComunDivisor(fra->numerador,fra->denominador);
    
    if(MCD>1){
        fra->numerador/=MCD;
        fra->denominador/=MCD;
    }
    
    

}


Fraccion Fraccion_Multiplicar(Fraccion *a, Fraccion *b){

    Fraccion fra;
    
    fra.numerador = a->numerador * b->numerador;
    fra.denominador = a->denominador * b->denominador;
    Fraccion_Simplificar(&fra);
    
    if(fra.denominador<0){
        fra.numerador *=-1;
        fra.denominador *=-1;
    }
        
    
    return fra;
}

Fraccion Fraccion_Dividir(Fraccion *dividendo, Fraccion *divisor){

    Fraccion fra;
    
    fra.numerador = dividendo->numerador * divisor->denominador;
    fra.denominador = dividendo->denominador * divisor->numerador;
    Fraccion_Simplificar(&fra);
    
    if(fra.denominador<0){
        fra.numerador *=-1;
        fra.denominador *=-1;
    }
    
    return fra;
}

Fraccion Fraccion_Sumar(Fraccion *a, Fraccion *b){

    Fraccion suma;
    suma.numerador= (a->numerador*b->denominador) +(b->numerador*a->denominador);
    suma.denominador= a->denominador*b->denominador;
    
    Fraccion_Simplificar(&suma);
    return suma;

}

Fraccion Fraccion_Restar(Fraccion *a, Fraccion *b){

    Fraccion resta;
    resta.numerador= (a->numerador*b->denominador) -(b->numerador*a->denominador);
    resta.denominador= a->denominador*b->denominador;
    
    Fraccion_Simplificar(&resta);
    return resta;

}

int Fraccion_Menor(Fraccion * fra1, Fraccion *fra2){

    if(fra1->denominador==1 && fra2->denominador ==1){
    
        if(fra1->numerador==fra2->numerador)
            return 0;
        
        else
            return (fra1->numerador < fra2->numerador)? 1:2;
    }
    
    else{
        long a,b;
        
        a = fra1->numerador*fra2->denominador;
        b = fra1->denominador*fra2->numerador;
        if(a==b)
            return 0;
        else
            return (a<b)? 1:2;
    }
    
    
}

int Fraccion_esMenorQueCero(Fraccion *f){
    Fraccion cero;
    Fraccion_setValue(&cero,0,1);
    if(Fraccion_Menor(f,&cero)==1)
        return 0;
    
    else return 1;

}

int Fraccion_esMayorQueCero(Fraccion *f){
    Fraccion cero;
    Fraccion_setValue(&cero,0,1);
    if(Fraccion_Menor(&cero,f)==1)
        return 0;
    
    else return 1;

}

int Fraccion_esIndeterminado(Fraccion *f){
    
    if(f->denominador==0)
        return 0;
    else return 1;

}             

int Fraccion_esCero(Fraccion *f){
    
    if(f->numerador==0 && f->denominador==1)
        return 0;
    else return 1;

}

void Fraccion_abs(Fraccion *f){

    f->numerador = (long) fabs(f->numerador);
    f->denominador = (long) fabs(f->denominador);


}